//bange_object.cpp
//Copyright (C) 2010-2011 Oscar (.teri) Triano

//This program is free software: you can redistribute it and/or modify
//it under the terms of the GNU General Public License as published by
//the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.

//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.

//You should have received a copy of the GNU General Public License
//along with this program.  If not, see <http://www.gnu.org/licenses/>.

#include <bange_object.hpp>

void bange::object::RegisterVM(lua_State *vm){
	luaL_Reg method[] = {
	{"Move", bangeobject_Move},
	{"Scale", bangeobject_Scale},
	{"Rotate", bangeobject_Rotate},
	{"SetCenter", bangeobject_SetCenter},
	{NULL, NULL}};
	luaL_newmetatable(vm, "bange::object_method");
	luaL_register(vm, NULL, method);
	lua_pop(vm, 1);
}

bange::object::object(lua_State *vm): bange::behavior(vm){
	this->deleted = false;
	this->visible = true;
}

bool bange::object::NewIndex(lua_State *vm){
	//object, key, data
	char key[64] = {0};
	strncpy(key, lua_tostring(vm, 2), 64);
	//drawable = this->drawable
	if (strcmp("deleted", key) == 0 && lua_isboolean(vm, 3)){
		this->deleted = static_cast<bool>(lua_toboolean(vm, 3));
		return true;}
	if (strcmp("visible", key) == 0 && lua_isboolean(vm, 3)){
		this->visible = static_cast<bool>(lua_toboolean(vm, 3));
		return true;}
	if (strcmp("x", key) == 0 && lua_isnumber(vm, 3)){
		drawable->SetX(lua_tonumber(vm, 3));
		return true;}
	if (strcmp("y", key) == 0 && lua_isnumber(vm, 3)){
		drawable->SetY(lua_tonumber(vm, 3));
		return true;}
	if (strcmp("scalex", key) == 0 && lua_isnumber(vm, 3)){
		drawable->SetScaleX(lua_tonumber(vm, 3));
		return true;}
	if (strcmp("scaley", key) == 0 && lua_isnumber(vm, 3)){
		drawable->SetScaleY(lua_tonumber(vm, 3));
		return true;}
	if (strcmp("rotation", key) == 0 && lua_isnumber(vm, 3)){
		drawable->SetRotation(lua_tonumber(vm, 3));
		return true;}
	if (strcmp("r", key) == 0 && lua_isnumber(vm, 3)){
		sf::Color color = drawable->GetColor();
		color.r = static_cast<sf::Uint8>(lua_tonumber(vm, 3));
		drawable->SetColor(color);
		return true;}
	if (strcmp("g", key) == 0 && lua_isnumber(vm, 3)){
		sf::Color color = drawable->GetColor();
		color.g = static_cast<sf::Uint8>(lua_tonumber(vm, 3));
		drawable->SetColor(color);
		return true;}
	if (strcmp("b", key) == 0 && lua_isnumber(vm, 3)){
		sf::Color color = drawable->GetColor();
		color.b = static_cast<sf::Uint8>(lua_tonumber(vm, 3));
		drawable->SetColor(color);
		return true;}
	if (strcmp("a", key) == 0 && lua_isnumber(vm, 3)){
		sf::Color color = drawable->GetColor();
		color.a = static_cast<sf::Uint8>(lua_tonumber(vm, 3));
		drawable->SetColor(color);
		return true;}
	if (strcmp("blendmode", key) == 0 && lua_isnumber(vm, 3)){
		drawable->SetBlendMode(static_cast<sf::Blend::Mode>(lua_tonumber(vm, 3)));
		return true;}
	return false;
}

bool bange::object::Index(lua_State *vm){
	//object, key
	char key[64] = {0};
	strncpy(key, lua_tostring(vm, 2), 64);
	//drawable = this->drawable
	if (strcmp("visible", key) == 0){
		lua_pushboolean(vm, this->visible);
		return true;}
	if (strcmp("x", key) == 0){
		sf::Vector2f pos = drawable->GetPosition();
		lua_pushnumber(vm, pos.x);
		return true;}
	if (strcmp("y", key) == 0){
		sf::Vector2f pos = drawable->GetPosition();
		lua_pushnumber(vm, pos.y);
		return true;}
	if (strcmp("scalex", key) == 0){
		sf::Vector2f scale = drawable->GetScale();
		lua_pushnumber(vm, scale.x);
		return true;}
	if (strcmp("scaley", key) == 0){
		sf::Vector2f scale = drawable->GetScale();
		lua_pushnumber(vm, scale.y);
		return true;}
	if (strcmp("rotation", key) == 0){
		lua_pushnumber(vm, drawable->GetRotation());
		return true;}
	if (strcmp("center", key) == 0){
		sf::Vector2f center = drawable->GetCenter();
		lua_createtable(vm, 0, 2);
		lua_pushnumber(vm, center.x);
		lua_setfield(vm, -1, "x");
		lua_pushnumber(vm, center.y);
		lua_setfield(vm, -1, "y");
		return true;}
	if (strcmp("r", key) == 0){
		sf::Color color = drawable->GetColor();
		lua_pushnumber(vm, color.r);
		return true;}
	if (strcmp("g", key) == 0){
		sf::Color color = drawable->GetColor();
		lua_pushnumber(vm, color.g);
		return true;}
	if (strcmp("b", key) == 0){
		sf::Color color = drawable->GetColor();
		lua_pushnumber(vm, color.b);
		return true;}
	if (strcmp("a", key) == 0){
		sf::Color color = drawable->GetColor();
		lua_pushnumber(vm, color.a);
		return true;}
	if (strcmp("blendmode", key) == 0){
		lua_pushnumber(vm, static_cast<lua_Number>(drawable->GetBlendMode()));
		return true;}
	lua_getfield(vm, LUA_REGISTRYINDEX, "bange::object_method");
	lua_getfield(vm, -1, key);
	if(lua_isfunction(vm, -1)){
		return true;}
	return false;
}

void bange::object::Move(float offsetx, float offsety){
	this->drawable->Move(offsetx, offsety);
}

void bange::object::Scale(float factorx, float factory){
	this->drawable->Scale(factorx, factory);
}

void bange::object::Rotate(float angle){
	this->drawable->Rotate(angle);
}

void bange::object::SetCenter(float centerx, float centery){
	this->drawable->SetCenter(centerx, centery);
}

bange::object::~object(){
	cout << "bange::simpleobject destructor for: " << this << endl;
}

static int bangeobject_Move(lua_State *vm){
	//object, offsetx, offsety
	bange::object *object = static_cast<bange::object *>(bange::base::GetBaseFromProxy(1, vm));
	object->Move(lua_tonumber(vm, 2), lua_tonumber(vm, 3));
	return 0;
}

static int bangeobject_Scale(lua_State *vm){
	//object, factorx, factory
	bange::object *object = static_cast<bange::object *>(bange::base::GetBaseFromProxy(1, vm));
	object->Scale(lua_tonumber(vm, 2), lua_tonumber(vm, 3));
	return 0;
}

static int bangeobject_Rotate(lua_State *vm){
	//simpleobject, factorx, factory
	bange::object *object = static_cast<bange::object *>(bange::base::GetBaseFromProxy(1, vm));
	object->Rotate(lua_tonumber(vm, 2));
	return 0;
}

static int bangeobject_SetCenter(lua_State *vm){
	//simpleobject, centerx, centery
	bange::object *object = static_cast<bange::object *>(bange::base::GetBaseFromProxy(1, vm));
	object->SetCenter(lua_tonumber(vm, 2), lua_tonumber(vm, 3));
	return 0;
}
